package br.com.arndroid.coupman.site;

import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import br.com.arndroid.coupman.model.CouponDAO;
import br.com.arndroid.lib.entity.EntityController;
import br.com.arndroid.lib.validation.ConstraintViolations;

public class SiteController implements EntityController<SitePOJO> {

	// Error constants:
	public static final String ERR_SITE_INVALID_NAME = "br.com.arndroid.coupman.ERR_SITE_INVALID_NAME";
	public static final String ERR_SITE_INVALID_URL = "br.com.arndroid.coupman.ERR_SITE_INVALID_URL";
	public static final String ERR_SITE_DUPLICATED_NAME = "br.com.arndroid.coupman.ERR_SITE_DUPLICATED_NAME";

	// Get Instance method:
	public static SiteController getInstance(Context context) {
		return new SiteController(context);
	}
	
	// Constructors:
	protected SiteController(Context context) {
		this(CouponDAO.getInstance(context));
	}
	
	protected SiteController(CouponDAO aDAO) {
		mDAO = aDAO;
	}

	private CouponDAO mDAO;

	@Override
	public long persist(SitePOJO vo) {
		//Site == null not allowed:
		if(vo == null)
			throw new IllegalArgumentException("Invalid site == null");

		/**
		 * This implementation don't make revalidations. This implementation rely
		 * on caller to pass a valid site. 
		 * Revalidations may be implemented with a flag for debug use sinalization
		 * (e.g, static boolean field in CouponController with accessors) and this
		 * method call revalidations based on that flag. 
		 */
		return mDAO.saveSite(vo);
	}

	@Override
	public boolean isPersistable(SitePOJO vo) {
		// Site == null not allowed:
		if(vo == null)
			throw new IllegalArgumentException("Invalid site == null");
		
		/**
		 * In this implementation for all not null sites returns true.
		 * A more restrictive implementation may be:
		 * If a update (site._id != null) - otherwise returns true or exception for illegal argument:
		 * 1. Find database row
		 * 2. Compare database x site field by field
		 * 3. If not equals (i.e, exists a change in entity attributes) returns true, otherwise returns false.
		 */
		
		/**
		 * Because returns null "all the time" this method isn't call from view...
		 */
		return true;
	}

	@Override
	public ConstraintViolations validate(SitePOJO site) {
		ConstraintViolations result = null;
		Long idByName;
		
		// Site == null not allowed:
		if(site == null)
			throw new IllegalArgumentException("Invalid site == null");
		
		// Name:
		if(TextUtils.isEmpty(site.name)) {
			if(result == null)
				result = new ConstraintViolations();
			result.addViolation(ERR_SITE_INVALID_NAME);
		} else {
			// Duplicate name:
			idByName = mDAO.getSiteIdByName(site.name);
			if(idByName != null && !idByName.equals(site._id)) {
				if(result == null)
					result = new ConstraintViolations();
				result.addViolation(ERR_SITE_DUPLICATED_NAME);
			}
		}
		
		// Url:
		if(site.url_uri != null && !site.url_uri.trim().equals("")) {
			// TODO: Implements url validation...
		}
		
		return result;
	}

	@Override
	public Cursor getAll() {
		return mDAO.getSites();
	}

	@Override
	public void remove(long id) {
		mDAO.removeSite(id);
	}

	@Override
	public SitePOJO getById(long id) {
		return mDAO.getSiteById(id);
	}
}
